package com.fan.chat.service.impl;

import com.alibaba.fastjson.JSON;
import com.fan.chat.component.ChatConfig;
import com.fan.chat.component.ChatGPTStreamComponent;
import com.fan.chat.component.context.ChatContextHolder;
import com.fan.chat.constant.ChatConstant;
import com.fan.chat.controller.request.SseEmitterRequest;
import com.fan.chat.controller.request.SseRequest;
import com.fan.chat.listener.CusSseStreamListener;
import com.fan.chat.model.JSONResult;
import com.fan.chat.service.ChatService;
import com.plexpt.chatgpt.ChatGPT;
import com.plexpt.chatgpt.ChatGPTStream;
import com.plexpt.chatgpt.entity.chat.ChatCompletion;
import com.plexpt.chatgpt.entity.chat.ChatCompletionResponse;
import com.plexpt.chatgpt.entity.chat.Message;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import java.util.ArrayList;
import java.util.List;

@Slf4j
@Service
public class ChatServiceImpl implements ChatService {

    @Autowired
    private ChatGPTStreamComponent chatGPTStreamComponent;

    @Autowired
    private ChatConfig chatConfig;

    @Autowired
    private ChatContextHolder chatContextHolder;

    @Override
    public void context(SseEmitterRequest request) {
        chatContextHolder.addMessage(request.getId(), request.getContext());
    }

    @Override
    public SseEmitter sseEmitter(SseRequest request) {
        SseEmitter sseEmitter = new SseEmitter(-1L);

        List<Message> messages = chatContextHolder.getListMessage(request.getId());

        ChatGPTStream chatGPTStream = chatGPTStreamComponent.getChatGPTStream();

        if (StringUtils.hasLength(request.getModel())) {
            ChatCompletion config = new ChatCompletion();
            BeanUtils.copyProperties(request, config);
            config.setMessages(messages);
            config.setStream(true);
            chatGPTStream.streamChatCompletion(config,
                    new CusSseStreamListener(sseEmitter));
        } else {
            chatGPTStream.streamChatCompletion(messages,
                    new CusSseStreamListener(sseEmitter));
        }

        return sseEmitter;
    }

    @Override
    public JSONResult<?> summaryTopic(SseEmitterRequest request) {

        ChatGPT chatGPT = ChatGPT.builder()
                .apiKeyList(chatConfig.getApiKey())
                .proxy(chatConfig.getProxy())
                .apiHost(chatConfig.getApiHost())
                .build()
                .init();

        List<Message> messages = request.getContext();
        messages.add(Message.of(ChatConstant.summaryTopicText));

        ChatCompletionResponse chatCompletionResponse = chatGPT.chatCompletion(messages);
        try {
            log.info("summaryTopic response: {}", JSON.toJSONString(chatCompletionResponse));
            String content = chatCompletionResponse.getChoices().get(0).getMessage().getContent();
            return JSONResult.success(content);
        } catch (Exception e) {
            return JSONResult.error();
        }
    }

}
